﻿//-------------------------------------------------------------------------------
// <copyright file="WebRequestHelper.cs" company="TaskyMedia LLC">
//     Copyright (c) TaskyMedia LLC.
// </copyright>
//-------------------------------------------------------------------------------

/*
 * Copyright (c) 2010, TaskyMedia LLC
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification, 
 * are permitted provided that the following conditions are met:
 *   Redistributions of source code must retain the above copyright notice, this 
 *     list of conditions and the following disclaimer.
 *   Redistributions in binary form must reproduce the above copyright notice, this
 *     list of conditions and the following disclaimer in the documentation and/or
 *     other materials provided with the distribution.
 *   Neither the name of TaskyMedia LLC nor the names of its contributors may be used
 *   to endorse or promote products derived from this software without specific prior
 *   written permission.
 *   
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
 * OF SUCH DAMAGE. 
 */

namespace FBGraphApi
{
    using System;
    using System.Globalization;
    using System.IO;
    using System.Net;

    /// <summary>
    /// Encapsulates the functionality of making web requests.
    /// </summary>
    internal class WebRequestHelper
    {
        /// <summary>
        /// Prevents a default instance of the <see cref="WebRequestHelper" /> class from being created.
        /// </summary>
        private WebRequestHelper()
        {
        }

        /// <summary>
        /// Performs a GET action on the specified URI and returns the result.
        /// </summary>
        /// <param name="uri">URI of the resource to retrieve.</param>
        /// <param name="requestParams">The request parameters.</param>
        /// <returns>
        /// Returns a <see cref="FBGraphApi.WebRequestResult"/> instance with the return data.
        /// </returns>
        public static WebRequestResult Get(string uri, params WebRequestParameter[] requestParams)
        {
            // Build the request URI
            Uri reqUri;
            if (requestParams.Length > 0)
            {
                reqUri = new Uri(String.Format(CultureInfo.InvariantCulture, "{0}?{1}", uri, WebRequestParameter.BuildQueryString(requestParams)));
            }
            else
            {
                reqUri = new Uri(uri);
            }

            // Set up the request
            HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(reqUri);
            req.Method = "GET";
            req.UserAgent = Configuration.ConfigurationSectionHandler.Default.UserAgent;
            req.AllowAutoRedirect = false;
            req.ServicePoint.Expect100Continue = false;

            try
            {
                // Get the response
                HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
                return ReadResult(resp);
            }
            catch (WebException ex)
            {
                if (ex.Status == WebExceptionStatus.ProtocolError)
                {
                    return new WebRequestResult(((HttpWebResponse)ex.Response).StatusCode);
                }
                else
                {
                    throw;
                }
            }
        }

        /// <summary>
        /// Reads the response from the <see cref="T:System.Net.HttpWebResponse" /> into an instance of the <see cref="FBGraphApi.WebRequestResult" /> class.
        /// </summary>
        /// <param name="response"><see cref="T:System.Net.HttpWebResponse" /> instance for the request to process.</param>
        /// <returns>The <see cref="FBGraphApi.WebRequestResult" /> representing the result of the request.</returns>
        private static WebRequestResult ReadResult(HttpWebResponse response)
        {
            WebRequestResult result = new WebRequestResult(response.StatusCode);

            // Read the response data if everything was OK (HTTP 200)
            if (response.StatusCode == HttpStatusCode.OK)
            {
                using (Stream s = response.GetResponseStream())
                {
                    byte[] buffer = new byte[4096];
                    int bytesRead = s.Read(buffer, 0, buffer.Length);
                    while (bytesRead > 0)
                    {
                        result.WriteChunk(buffer, 0, bytesRead);
                        bytesRead = s.Read(buffer, 0, buffer.Length);
                    }
                }
            }

            return result;
        }
    }
}
